package com.enation.app.javashop.consumer.shop.goods;

import com.enation.app.javashop.consumer.core.event.TradeIntoDbEvent;
import com.enation.app.javashop.core.base.message.OrderStatusChangeMsg;
import com.enation.app.javashop.core.base.rabbitmq.AmqpExchange;
import com.enation.app.javashop.core.client.goods.GoodsQuantityClient;
import com.enation.app.javashop.core.client.trade.OrderClient;
import com.enation.app.javashop.core.goods.model.enums.QuantityType;
import com.enation.app.javashop.core.goods.model.vo.GoodsQuantityVO;
import com.enation.app.javashop.core.goods.service.GoodsStockManager;
import com.enation.app.javashop.core.promotion.groupbuy.service.GroupbuyGoodsManager;
import com.enation.app.javashop.core.promotion.seckill.service.SeckillGoodsManager;
import com.enation.app.javashop.core.promotion.shetuan.service.ShetuanGoodsManager;
import com.enation.app.javashop.core.promotion.tool.model.dto.PromotionDTO;
import com.enation.app.javashop.core.promotion.tool.model.enums.PromotionTypeEnum;
import com.enation.app.javashop.core.trade.cart.model.vo.CartPromotionVo;
import com.enation.app.javashop.core.trade.cart.model.vo.CartSkuVO;
import com.enation.app.javashop.core.trade.order.model.dos.OrderDO;
import com.enation.app.javashop.core.trade.order.model.dto.OrderDTO;
import com.enation.app.javashop.core.trade.order.model.enums.OrderStatusEnum;
import com.enation.app.javashop.core.trade.order.model.vo.TradeVO;
import com.enation.app.javashop.framework.exception.ResourceNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;

/**
 * 商品锁库存操作消费者
 * @author kingapex
 * @version 1.0
 * @since 7.1.0
 * 2019-07-26
 */
@Component
public class GoodsStockLockConsumer implements TradeIntoDbEvent {
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private GoodsStockManager goodsStockManager;



    /**
     * 处理订单创建扣减库存
     *
     * @param tradeVO
     */
    @Override
    public void onTradeIntoDb(TradeVO tradeVO) {

        if (tradeVO == null) {
            throw new ResourceNotFoundException("交易不存在");
        }
        //获取交易中的订单集合
        List<OrderDTO> orderDTOS = tradeVO.getOrderList();

        //此变量标识订单是否全部更新成功，只有订单状态全部更新成功，交易状态才可以更新为已确认，
        // 只要有一个订单更新状态失败，则交易失败，但是不影响订单
        boolean bool = true;

        for (OrderDTO order : orderDTOS) {
            bool = orderIntoDb(order);
            if(!bool){
                break;
            }
        }

        //处理交易,如果此交易中有一个订单状态更新失败，则此交易状态为出库失败
        if (!bool) {
            goodsStockManager.updateTradeState(tradeVO.getTradeSn(), 0, OrderStatusEnum.INTODB_ERROR);
        } else {
            goodsStockManager.updateTradeState(tradeVO.getTradeSn(), 0, OrderStatusEnum.CONFIRM);
        }

    }


    /**
     * 订单入库
     *
     * @param order
     * @return
     */
    private boolean orderIntoDb(OrderDTO order) {


        //-------------先尝试锁优惠库存-------------
        //如果锁库失败，自行回滚
        boolean promotionLockResult = goodsStockManager.lockPromotionStock(order);

        OrderStatusEnum status;

        boolean normalLockResult = false;

        //-------------尝试锁普通库存------
        //如果优惠库存锁成功，尝试锁普通库存
        if (promotionLockResult) {
            //如果锁库失败，自行回滚(不需调用者处理)
            normalLockResult = goodsStockManager.lockNormalStock(order);
        }

        boolean lockResult = normalLockResult && promotionLockResult;

        //如果锁库成功，订单状态为出库成功，即OrderStatusEnum.CONFIRM;
        //但如果金额为零，则直接付款成功
        if (lockResult) {

            //如果待支付金额为0，则状态变成已付款
            if (order.getNeedPayMoney() == 0 ) {
                status = OrderStatusEnum.PAID_OFF;
            } else {
                status = OrderStatusEnum.CONFIRM;
            }

        } else {
            //锁库失败
            status = OrderStatusEnum.INTODB_ERROR;
        }

        //-------------更新订单状态------------
        // 如果订单状态更新失败，重试三次，如果最终失败则回滚库存
        boolean updateResult = goodsStockManager.updateState(order.getSn(), 0, status);

        //如果更新成功则发mq消息
        if (updateResult) {

            //此处说明订单状态更新成功，则发送订单状态变化消息
            OrderStatusChangeMsg orderStatusChangeMsg = new OrderStatusChangeMsg();
            orderStatusChangeMsg.setOldStatus(OrderStatusEnum.NEW);
            orderStatusChangeMsg.setNewStatus(status);
            OrderDO orderDO = new OrderDO(order);
            orderDO.setTradeSn(order.getTradeSn());
            orderDO.setOrderStatus(status.value());
            orderStatusChangeMsg.setOrderDO(orderDO);

            this.amqpTemplate.convertAndSend(AmqpExchange.ORDER_STATUS_CHANGE,
                    AmqpExchange.ORDER_STATUS_CHANGE + "_ROUTING",
                    orderStatusChangeMsg);

        } else {

            //-----回滚所有的库存 -----

            //回滚普通商品的库存
            goodsStockManager.rollbackNormal(order);

            //回滚优惠库存
            goodsStockManager.rollbackPromotionStock(order);


        }

        //订单锁库成功 并且状态更新成功才算成功
        return updateResult && lockResult;

    }


}
